<?php
/**
 * Created by PhpStorm.
 * User: 小灰灰
 * Date: 2023-11-08
 * Time: 11:34:08
 * Info:
 */

namespace app\common\model;

use libs\Tree2;

class Category extends TimeInit
{

    public function models()
    {
        return $this->hasOne('app\common\model\Models', 'id', 'model_id');
    }

    public function childids()
    {
        return $this->hasMany('app\common\model\CategoryChildid', 'cate_id', 'id');
    }

    /**
     * 追加属性
     *
     * @param $value
     * @param $data
     *
     * @return string
     */
    public function getTypeTextAttr($value, $data)
    {
        $option = ['category' => '栏目首页', 'list' => '列表栏目', 'link' => '其他链接'];

        return $option[$data['type']];
    }

    /**
     * 获取栏目列表
     */
    public static function getCategoryList($params = [])
    {
        $data = [];
        if ($params) {
            $field = $params['field'];
            $order = $params['order'];
        }
        $count = Category::count();
        $list  = Category::alias('c')->field('c.*,m.name as model_name')->leftjoin('cms_models m',
            'm.id = c.model_id')->order('c.'.$field, $order)->select();
        foreach ($list as $key => $v) {
            $v['index_tpl'] = $v['index_tpl'] ? $v['index_tpl'].'.html' : '';
            $v['list_tpl']  = $v['list_tpl'] ? $v['list_tpl'].'.html' : '';
            $v['show_tpl']  = $v['show_tpl'] ? $v['show_tpl'].'.html' : '';
        }
        $data['list']  = $list ?? [];
        $data['count'] = $count ?? [];

        return $data;
    }

    /**
     * 文章模块获取栏目名称
     * @return void
     */
    public function getPidCategoryList($flag = false, $parentId = 0)
    {
        $where       = function ($query) use ($parentId) {
            if ( ! empty($parentId)) {
                $query->where('pid', $parentId);
            }
        };
        $list        = $this->field('id,pid,name,sort,model_id')->where($where)->select()->toArray();
        $pidMenuList = $this->buildPidMenu($parentId, $list);
        if ($flag) {
            $pidMenuList = array_merge([
                [
                    'id'   => 0,
                    'pid'  => 0,
                    'name' => '顶级栏目',
                ]
            ], $pidMenuList);
        }

        return $pidMenuList;
    }

    protected function buildPidMenu($pid, $list, $level = 0)
    {
        $newList = [];
        foreach ($list as $vo) {
            if ($vo['pid'] == $pid) {
                $level++;
                foreach ($newList as $v) {
                    if ($vo['pid'] == $v['pid'] && isset($v['level'])) {
                        $level = $v['level'];
                        break;
                    }
                }
                $vo['level'] = $level;
                if ($level > 1) {
                    $repeatString = "&nbsp;&nbsp;";
                    $markString   = str_repeat("{$repeatString}├{$repeatString}", $level - 1);
                    $vo['name']   = $markString.$vo['name'];
                }
                $newList[] = $vo;
                $childList = $this->buildPidMenu($vo['id'], $list, $level);
                ! empty($childList) && $newList = array_merge($newList, $childList);
            }

        }

        return $newList;
    }

    /**
     * 前端模版标签获取tree栏目
     */
    public function tpCateListTree($id, $field, $limit, $order, $tree = 1)
    {
        $where = function ($query) use ($id) {
            $query->where('status', 1);
            if ( ! empty($id)) {
                $query->where('pid', $id);
            }
        };
        if ( ! empty($limit)) {
            //如果有数量限制，只取pid=0的顶级栏目，因为sql的LIMIT避免不了子栏目的问题
            if (empty($field)) {
                $list = self::with([
                    'models' => function ($query) {
                        $query->field('id,name,alias');
                    }
                ])->withoutField('create_time,update_time,delete_time')->where($where)->where('pid',
                    0)->limit($limit)->order($order)->select()->toArray();
            } else {
                $list = self::field($field)->with([
                    'models' => function ($query) {
                        $query->field('id,name,alias');
                    }
                ])->where($where)->where('pid', 0)->limit($limit)->order($order)->select()->toArray();
            }
        } else {
            if (empty($field)) {
                $list = self::with([
                    'models' => function ($query) {
                        $query->field('id,name,alias');
                    }
                ])->withoutField('create_time,update_time,delete_time')->where($where)->order($order)->select()->toArray();
            } else {
                $list = self::field($field)->with([
                    'models' => function ($query) {
                        $query->field('id,name,alias');
                    }
                ])->where($where)->order($order)->select()->toArray();
            }
        }
        foreach ($list as $key => $v) {
            $list[$key]['childids'] = explode(',', $this->get_arrchildid($v['id']));
        }

        //URL 模式
        $url_mode = get_config('url_mode');
        //Url 格式
        $url_format = get_config('url_format');

        //根据后台配置，获取url地址规则
        if ($url_mode == 1 && $url_format == 2) {
            //伪静态 -父级目录/当前目录
            return $this->buildMenu($list);
        } elseif ($url_mode == 1 && $url_format != 2) {
            //伪静态
            if ($url_format == 1) {
                //当前目录
                foreach ($list as $key => $value) {
                    //动态规则
                    $list[$key]['href'] = "/".$value['dirname']."/";
                }
                if ($tree) {
                    return get_tree($list, $id);
                } else {
                    return $list;
                }
            } else {
                // 模型目录/当前目录
                foreach ($list as $key => $s) {
                    $list[$key]['href'] = "/".$s['models']['alias']."/".$s['dirname']."/";
                }
                if ($tree) {
                    return get_tree($list, $id);
                } else {
                    return $list;
                }
            }
        } else {
            //动态
            foreach ($list as $key => $value) {
                //动态规则
                //$href = "/index/lists/catid/".$value['id'];
                $href = $this->buildUrl("", $value);

                $list[$key]['href'] = $href;
            }

            if ($tree) {
                return get_tree($list, $id);
            } else {
                return $list;
            }
        }
    }

    /**
     * 前端模版标签获取单个栏目信息
     *
     * @param $id
     *
     * @return void
     */
    public function getCateInfo($id, $field = "")
    {
        if (empty($id)) {
            return ['code' => 0, 'msg' => 'id参数错误'];
        }
        $data = self::with([
            'models' => function ($query) {
                $query->field('id,name,alias');
            }
        ])->where('id', $id)->where('status', 1)->find();
        if (empty($data)) {
            return ['code' => 0, 'msg' => '获取数据失败'];
        }
        $data = is_object($data) ? $data->toArray() : $data;

        if ($field == 'href') {
            //URL 模式
            $url_mode = get_config('url_mode');
            //Url 格式
            $url_format = get_config('url_format');

            if ($url_mode == 1) {
                // 伪静态地址
                if ($url_format == 1) {
                    //当前目录
                    $href = "/".$data['dirname']."/";
                } elseif ($url_format == 2) {
                    // 父级目录/当前目录
                    $lists = self::where('status', 1)->select()->toArray();
                    $href  = "/".$this->getParentDirnamesString($lists, $data['id'])."/";
                } else {
                    //模型目录
                    $href = "/".$data['models']['alias']."/".$data['dirname']."/";
                }
            } else {
                //动态地址
                $href = "/index/lists/catid/".$data['id'];
            }
            $data['href'] = $href;
        }
        $data['childids'] = $this->get_arrchildid($data['id'],true);

        if ( ! empty($field)) {
            $data = $data[$field] ?? '';
        }

        return ['code' => 200, 'msg' => 'ok', 'data' => $data];
    }

    /**
     * 将菜单数组转换成属性菜单数组
     *
     * @param $menu
     * @param $parentId
     *
     * @return array
     */
    private function buildMenu($menu, $parentId = 0)
    {
        $result = [];
        foreach ($menu as $item) {
            if ($item['pid'] == $parentId) {
                $children = $this->buildMenu($menu, $item['id']);
                if ($children) {
                    $item['sub'] = $children;
                }
                $item['href'] = $this->generateHref($item, $menu);
                $result[]     = $item;
            }
        }

        return $result;
    }

    /**
     * 根据属性菜单数组，获取父级的dirname目录值并拼接
     *
     * @param $item
     * @param $menu
     *
     * @return string
     */
    private function generateHref($item, $menu)
    {
        $path     = [];
        $parentId = $item['pid'];
        while ($parentId != 0) {
            foreach ($menu as $menuItem) {
                if ($menuItem['id'] == $parentId) {
                    array_unshift($path, $menuItem['dirname']);
                    $parentId = $menuItem['pid'];
                    break;
                }
            }
        }
        $path[] = $item['dirname'];

        return '/'.implode('/', $path).'/';
    }

    /**
     * 获取所有父级的dirname目录
     *
     * @param $array
     * @param $childId
     * @param $dirnames
     *
     * @return void
     */
    private function getAllParentDirnames($array, $childId, &$dirnames)
    {
        foreach ($array as $item) {
            if ($item['id'] == $childId) {
                $dirnames[] = $item['dirname'];
                if (isset($item['pid'])) {
                    $this->getAllParentDirnames($array, $item['pid'], $dirnames);
                }
                break;
            }
        }
    }

    /**
     * 根据获取到的父级数组，拼接为正常地址
     *
     * @param $array
     * @param $childId
     *
     * @return string
     */
    private function getParentDirnamesString($array, $childId)
    {
        $dirnames = [];
        $this->getAllParentDirnames($array, $childId, $dirnames);

        return implode('/', array_reverse($dirnames));
    }

    /**
     * 生成url地址
     *
     * @param      $value
     * @param      $data
     * @param bool $domain
     */
    protected function buildUrl($value, $data, $domain = false)
    {
        if (empty($value) && $data['model_id'] > 0) {
            $site = get_config(); // 获取伪静态规则
            if ($site['url_mode'] == 1 && ! empty($site['url_rewrite'])) {
                $param = $data;
            } else {
                $param = ['catname' => $data['dirname']];
            }

            return index_url('/index/lists', $param, '', $domain);
        } else {
            if ($data['type'] == 'link' && is_numeric($value)) {
                $info = $this->where(['id' => $value])->find();
                if ($info) {
                    return $info['url'];
                }
            }
        }

        return $value;
    }

    /**
     * 面包屑导航
     *
     * @param $tag  array 标签
     * @param $cate array 栏目信息
     *
     * @return string
     */
    public function getBreadcrumb($tag, $cate = [])
    {
        $home_url   = '/';
        $home_title = "首页";

        $catid = ! empty($tag['catid']) ? $tag['catid'] : ($cate['id'] ?? '');
        if (empty($catid)) {
            return '';
        }

        $cacheID = to_guid_string($tag);
        if ( ! app()->isDebug() && $cacheData = cache($cacheID)) {
            return $cacheData;
        }

        $str = '<a href="'.$home_url.'" class="'.$tag['class'].'">'.$home_title.'</a>';
        if ( ! is_numeric($catid)) {
            return $str;
        }

        $tempArr = [];
        $arr     = $this::with([
            'models' => function ($query) {
                $query->field('id,name,alias');
            }
        ])->where(['id' => $catid, 'status' => 1])->find();
        if (empty($arr)) {
            return $str;
        }

        $tempArr[] = $arr->toArray();
        while (true) { // 循环获取上级
            $arr = $this::with([
                'models' => function ($query) {
                    $query->field('id,name,alias');
                }
            ])->where(['id' => $arr['pid'], 'status' => 1])->find();
            if (empty($arr)) {
                break;
            }
            $tempArr[] = $arr->toArray();
        }

        for ($i = count($tempArr) - 1; $i >= 0; $i--) {
            if ($catid != $tempArr[$i]['id']) {
                $str .= $tag['symbol'].'<a href="'.$tempArr[$i]['link'].'" class="'.$tag['class'].'">'.$tempArr[$i]['name'].'</a>';
            } else {
                if ($tag['isclick'] == 1) {
                    //URL 模式
                    $url_mode = get_config('url_mode');
                    //Url 格式
                    $url_format = get_config('url_format');
                    if ($url_mode == 1) {
                        // 伪静态地址
                        if ($url_format == 1) {
                            //当前目录
                            $href = "/".$tempArr[$i]['dirname']."/";
                        } elseif ($url_format == 2) {
                            // 父级目录/当前目录
                            $lists = self::where('status', 1)->select()->toArray();
                            $href  = "/".$this->getParentDirnamesString($lists, $tempArr[$i]['id'])."/";
                        } else {
                            //模型目录
                            $href = "/".$tempArr[$i]['models']['alias']."/".$tempArr[$i]['dirname']."/";
                        }
                    } else {
                        //动态地址
                        $href = "/index/lists/catid/".$tempArr[$i]['id'];
                    }
                    $cateUrl = $href;

                    $str .= $tag['symbol'].'<a href="'.$cateUrl.'" class="'.$tag['currentstyle'].'">'.$tempArr[$i]['name'].'</a>';
                } else {
                    $str .= $tag['symbol'].'<span class="'.$tag['currentstyle'].'">'.$tempArr[$i]['name'].'</span>';
                }
            }
        }
        // 结果进行缓存
        if ( ! app()->isDebug()) {
            cache($cacheID, $str, 86400, 'category_tag');
        }

        return $str;
    }

    /**
     * 获取子栏目ID列表
     */
    public function get_arrchildid($catid, $withself = false)
    {
        static $tree;
        if ( ! $tree) {
            $tree = Tree2::instance();
            $tree->init(Category::where('status', 1)->order('id asc')->field('id,pid,name')->select()->toArray(),
                'pid');
        }
        $childIds = $tree->getChildrenIds($catid, $withself);

        return implode(',', $childIds);
    }
}
